<?php
namespace app\api\controller;
use app\common\controller\HomeBase;
use app\common\model\Article;
use app\common\model\SendLog;
use app\common\service\SnsOauthService;
use app\user\model\Login as Model;
use app\user\model\User;
use app\user\model\UserLoginLog;
use app\user\model\UserOauth;
use app\user\model\UserRichesLog;
use think\facade\Request;

class Login extends HomeBase
{
    protected $regOpenType=3;
    protected $regTypeStr='邮箱或手机号';
    protected $objectName = [
        0 => '禁止',
        1 => '邮箱',
        2 => '手机号',
        3 => '邮箱或手机号',
    ];
    protected $sendTypeName = [
        'REG' => '注册',
        'FORGET' => '找回密码',
        'LOGIN' => '登录',

    ];

    public function initialize(){
        parent::initialize();
   }

    public function index()
    {
        if(UserLoginLog::getTodayErrorCount()>5){
            return json(array('code' => 0, 'msg' => '登录错误次数超限，请稍后再试'));
        }
        $redirect=session('login_redirect')?session('login_redirect'):__url('user/index/index');
        $res=Model::login($this->params,1);
        if($res['code']==1){
            return success('登录成功',['redirect'=>$redirect]);
        }else {
            return json($res);
        }
    }

    public function sendmsg()
    {
        $only=['object', 'captcha','type'];
        $rule = [
            'object|手机号或邮箱'       => 'require',
            'captcha|图片验证码'       => 'require'
        ];
        $data=validate_ext($only,$rule,1);
        if(isset($data['code'])&&$data['code']===0){
            return json($data);
        }

        $codeType=strtoupper($data['type']);
        $type=explode('_',$codeType)[0];
        $uid=cacheUserid();
        if(!$uid&&in_array($type,['UNBIND','BIND'])){
            return fail('未登录');
        }elseif($uid&&in_array($type,['REG','FORGET'])){
            return fail('已登录禁止该操作');
        }
        $object = $data['object'];
        $objectType = checkIsPhoneOrEmail($object,3);
        if (!$objectType) {
            return fail($this->regTypeStr.'格式不正确');
        }
        if ($objectType == 2) {
            $map['mobile'] = $object;
            $otherObject='email';
        } else {
            $map['email'] = $object;
            $otherObject='mobile';
        }
        $find = (new User())->where($map)->find();
        if($find&&in_array($type,['REG','BIND'])) {
            return json(array('code' => 0, 'msg' => $this->objectName[$objectType] . '已存在', 'data' => []));
        }elseif($find&&$type=='UNBIND'){
            if($find->id!=$uid) {
                return json(array('code' => 0, 'msg' => $this->objectName[$objectType] . '填写错误', 'data' => []));
            }elseif($find->$otherObject=='') {
                return json(array('code' => 0, 'msg' => $this->objectName[3] . '必须保留一个绑定', 'data' => []));
            }
        }elseif(in_array($type,['FORGET','UNBIND'])&&!$find) {
            return json(array('code' => 0, 'msg' => $this->objectName[$objectType] .'没注册', 'data' => []));
        }elseif(in_array($type,['LOGIN'])&&!$find&&!sysconfig('switch.register')) {
            return json(array('code' => 0, 'msg' => $this->objectName[$objectType] . '没注册', 'data' => []));
        }
        $sendResult=SendLog::sendCode($object,$objectType,$codeType);
        if (@$sendResult['code'] == 1) {
            return json(array('code' => 1, 'msg' => '验证码已发送到你的' . $this->objectName[$objectType] . '5分钟内有效，请及时操作！', 'data' => []));
        } else {
            return json(array('code' => 0, 'msg' => $sendResult['msg'], 'data' => []));
        }
    }



    public function checkwxlogin(){
        $data = $this->params;
        if(!isset($data['suijima'])){
            return json(array('code' => 0, 'msg' => 'GUN'));
        }
        $path=runtime_path() .'../'.$data['suijima'];
        $res=file_get_contents($path);
        if($res!='0'){
            if(is_numeric($res)){
                session('userid',$res);
            }
            @unlink($path);
            return json(array('code' => 1, 'msg' => 'SUCCESS','data'=>$res));
        }
        return json(array('code' => 0, 'msg' => 'FAILD'));
    }


    public function wechartScan()
    {
        if (!isset($_SERVER['HTTP_USER_AGENT']) || strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') === false) {
            dd('必须用手机微信扫码此页');
        }
        $params = $this->params;
        if (!isset($params['ws'])) {
            dd('参数不合规');
        }
        $paramstr = decrypt(str_replace(' ',"+",$params['ws']));
        $res = json_decode($paramstr, true);
        if (!is_array($res)) {
            dd('非法操作'.$params['ws']);
        }
        $suijima = $res['suijima'];
        if ($res['expired'] < time()) {
            @unlink(runtime_path() .'../'.$suijima);
            $this->error('超时，请重新生成二维码再扫描', '');
        }

        if($res['userid']){
            session('userid',$res['userid']);
            session('bind_wechart', 1);
        }else{
            session('userid',null);
        }
        session('suijima', $suijima);
        return SnsOauthService::auth('wechart');
    }

    public function register()
    {
        //判断cookie
        if(cacheUserid()){
            $this->error('已经登录，不能再注册', '');
        }
        $only=['username', 'captcha','password'];
        $rule = [
            'username|用户名'       => 'require|unique:user,username',
            'captcha|验证码'       => 'require',
            'password|密码'       => 'require|length:6,18',
        ];
        $other=[];
        if(isset($_POST['promo_code'])){
            $other['promo_code']=$_POST['promo_code'];
        }
        $data=validate_ext($only,$rule,1,$other);
        if(isset($data['code'])&&$data['code']==0){
            return json($data);
        }
        //检测是不是有权限注册
        //注册积分

        $res=User::createNew($data);
        $regScore=sysconfig('score.reg_award');
        if($regScore){
            UserRichesLog::note($regScore,$res->id,'新用户注册获系统奖励',1,0,'REGISTER');
        }
        $data['object']=$data['username'];
        unset($data['captcha']);
        $res=Model::login($data,0);
        if($res['code']==1){
            return json(array('code' => 1, 'msg' => '注册成功', 'data' => ['redirect'=>__url('user/index/index')]));
        }
        return json($res);
    }

    public function check(){
        $code = 2;
        $msg = 'offline';
        $data['status'] = false;
        $data['addr'] = $this->request->ip();
        $uid=cacheUserid();
        if ($uid) {
            $code = 1;
            $msg = 'online';
            $data['status'] = true;
            $data1 = (new User())->alias('a')->join('user_attribute b','a.id=b.user_id','left')
                ->where('a.id', $uid)
                ->field('uuid,avatar,praise_num,nickname')
                ->find();
            if($data1) {
                $data = array_merge($data, $data1->toArray());
                $data['posted_num']=(new Article())->where('user_id', $uid)->count('user_id');
            }else{
                session('userid', null);
                cookie('userid', null);
                $data=[];
            }
        }
        return json(array(
            'code' => $code,
            'msg' => $msg,
            'data' => $data,
        ));
    }

    /**
     * 用户退出
     * @return mixed
     */
    public function out()
    {
        session('userid', null);
        cookie('userid', null);
        $returnUrl= __url('index/index/index');
        if (Request::isPost()) {
            return json(array('code' => 1, 'msg' => '退出成功', 'data' => ['redirect' =>$returnUrl]));
        }else{
            $this->success('退出成功',[],$returnUrl);
        }
    }

    public function forgetpass(){
        $data=$this->params;
        $postType = $data['post_type'];
        $model=new User();
        if ($postType == 'step1') {
            if (!captcha_check($data['captcha'])) {
                return json(array('code' => 0, 'msg' => '图形码错误', 'data' => []));
            }
            $object = $data['object'];
            $objectType = checkIsPhoneOrEmail($object,$this->regOpenType);
            if (!$objectType) {
                return json(array('code' => -1, 'msg' => $this->objectName[$objectType].'格式不正确', 'data' => []));
            }
            if ($objectType == 2) {
                $map['mobile'] = $object;
            } else {
                $map['email'] = $object;
            }
            $find = $model->where($map)->find();
            if (!$find) {
                return json(array('code' => 0, 'msg' => $this->objectName[$objectType].'没有注册过账号', 'data' => []));
            }
            if ($find->status < 1) {
                return json(array('code' => 0, 'msg' => '账号已禁用', 'data' => []));
            }
            $sendResult=SendLog::sendCode($object,$objectType,'FORGET');
            if (@$sendResult['code'] == 1) {
                //生成加密字符串
                $encoded['object_type'] = $objectType;
                $encoded['object'] = $object;
                $encoded['step'] = 2;
                $key = encrypt(json_encode($encoded));
                $redirect = __url('user/login/forget') . '?key=' . $key;
                return json(array('code' => 1, 'msg' => '验证码已发送到你的' .$this->objectName[$objectType] . '5分钟内有效，请及时操作！',
                    'data' => [ 'redirect' => $redirect]));
            } else {
                return json(array('code' => 0, 'msg' => '验证码发送失败，原因：' . $sendResult['msg'], 'data' => []));
            }

        }elseif ($postType == 'step2') {
            $object=$data['object'];
            $objectType=$data['object_type'];
            $smsCode=$data['sms_code'];
            $res = SendLog::codeCheck($smsCode,$object, $objectType, 'FORGET');
            if ($res['code'] != 1) {
                return json($res);
            }
            if ($objectType == 1) {
                $where['email'] = $object;
            } else {
                $where['mobile'] = $object;
            }
            $user = $model->where($where)->find();
            if (!$user) {
                return json(array('code' => 0, 'msg' => '非法操作', 'data' => []));
            }
            $encoded['salt'] = $user['salt'];
            $encoded['step'] = 3;
            $encoded['sms_code'] = $smsCode;
            $encoded['object'] = $object;
            $encoded['object_type'] = $objectType;
            $key =encrypt(json_encode($encoded));
            $redirect = __url('user/login/forget') . '?key=' . $key;
            return json(array('code' => 1, 'msg' => '验证码正确',
                'data' => ['redirect' => $redirect]));

        }elseif ($postType == 'step3') {
            //检测codeId
            $object=remove_xss($data['object']);
            $objectType=remove_xss($data['object_type']);
            if($data['password']!=$data['password_confirm']){
                return json(array('code' => 0, 'msg' => '两次输入的密码不一致', 'data' => []));
            }
            $codeItem = SendLog::codeCheck($data['sms_code'],$object, $objectType, 'FORGET');

            if (!$codeItem['code']) {
                return json($codeItem);
            }
            $where['salt'] = $data['salt'];
            $user = $model->where($where)->find();
            if (!$user) {
                return json(array('code' => 0, 'msg' => '非法请求，用户未找到', 'data' => []));
            }
            $user->password = md5($data['password'] . $data['salt']);
            $user->save();

            SendLog::codeSetUsed($codeItem['data']['id']);
            return json(array('code' => 1, 'msg' => '密码重置成功',
                'data' => ['redirect' => __url('user/login/index')]));
        } else {
            return json(array('code' => 0, 'msg' => '非法请求', 'data' => []));
        }
    }

    //绑定和解绑合并
    public function unbind_applogin()
    {
        $userId = cacheUserid();
        if (!$userId) {
            return json(array('code' => -1, 'msg' => '没有登录', 'data' => []));
        }

        $only=['object', 'sms_code','object_type','type'];
        $rule = [
            'type|类型'       => 'require',
            'sms_code|验证码'       => 'require'
        ];
        $data=validate_ext($only,$rule);
        if(isset($data['code'])&&$data['code']===0){
            return json($data);
        }
        $codeType = $data['type'];
        $arr=explode('_',$codeType);
        $type=$arr[0];
        $app=$arr[1];
        $object = $data['object'];
        $code = $data['sms_code'];
        $objectType = $data['object_type'];

        $objectTypeCheck = checkIsPhoneOrEmail($object,$objectType);
        if (!$objectTypeCheck) {
            return json(array('code' => -1, 'msg' => '格式不正确', 'data' => []));
        }
        //检测验证码
        $res = SendLog::codeCheck($code, $object, $objectTypeCheck, strtoupper($codeType));
        if ($res['code'] != 1) {
            return json(array('code' => 2, 'msg' => $res['msg'], 'data' => []));
        }
        if ($objectType == 2) {
            $field='mobile';
        } else {
            $field='email';
        }
        $find = (new UserOauth())->where('user_id',$userId)->where('type',$app)->find();

        if(!$find){
            return json(array('code' => 0, 'msg' => '本未绑定，不必解绑', 'data' => []));
        }


        if ($find->delete()) {
            SendLog::codeSetUsed($res['data']['id']);
            return json(array('code' => 1, 'msg' => '操作成功', 'data' => []));
        } else {
            return json(array('code' => 0, 'msg' => '操作失败', 'data' => []));
        }
    }

    //绑定和解绑合并
    public function bind()
    {
        $userId = cacheUserid();
        if (!$userId) {
            return json(array('code' => -1, 'msg' => '没有登录', 'data' => []));
        }

        $only=['object', 'sms_code','object_type','type'];
        $rule = [
            'type|类型'       => 'require',
            'sms_code|验证码'       => 'require',
//            'object_type|类型'       => 'require',
        ];
        $data=validate_ext($only,$rule);
        if(isset($data['code'])&&$data['code']===0){
            return json($data);
        }
        $codeType=strtoupper($data['type']);
        $type=explode('_',$codeType)[0];
        $object = $data['object'];
        $code = $data['sms_code'];
        $objectType = $data['object_type'];

        $objectTypeCheck = checkIsPhoneOrEmail($object,$objectType);
        if (!$objectTypeCheck) {
            return json(array('code' => -1, 'msg' => '格式不正确', 'data' => []));
        }
        //检测验证码
        $res = SendLog::codeCheck($code, $object, $objectTypeCheck, $codeType);
        if ($res['code'] != 1) {
            return json(array('code' => 2, 'msg' => $res['msg'], 'data' => []));
        }
        if ($objectType == 2) {
            $field='mobile';
        } else {
            $field='email';
        }
        $find = (new User())->find($userId);

        if($type=='BIND'&&$find->$field){
            return json(array('code' => 0, 'msg' => '已绑定，要绑定其他的需先解绑', 'data' => []));
        }elseif($type=='UNBIND'&&!$find->$field){
            return json(array('code' => 0, 'msg' => '本未绑定，不必解绑', 'data' => []));
        }

        if($type=='BIND'){
            $find->$field=$object;
        }else{
            $find->$field='';
        }
        if ($find->save()) {
            SendLog::codeSetUsed($res['data']['id']);
            return json(array('code' => 1, 'msg' => '操作成功', 'data' => []));
        } else {
            return json(array('code' => 0, 'msg' => '操作失败', 'data' => []));
        }
    }
}

